<script setup lang="ts">
import * as THREE from 'three'
import { ref, onMounted } from 'vue'

const domEl = ref(null)

const demoList = ref([
  { positionList: [2, 0, 0], upList: [0, 1, 0], lookList: [0, 0, 0] },
  { positionList: [0, 2, 0], upList: [0, 1, 0], lookList: [0, 0, 0] },
  { positionList: [0, 0, 2], upList: [0, 1, 0], lookList: [0, 0, 0] },
  { positionList: [2, 0, 0], upList: [1, 0, 0], lookList: [0, 0, 0] },
  { positionList: [0, 2, 0], upList: [1, 0, 0], lookList: [0, 0, 0] },
  { positionList: [0, 0, 2], upList: [1, 0, 0], lookList: [0, 0, 0] },
  { positionList: [2, 0, 0], upList: [0, 0, 1], lookList: [0, 0, 0] },
  { positionList: [0, 2, 0], upList: [0, 0, 1], lookList: [0, 0, 0] },
  { positionList: [0, 0, 2], upList: [0, 0, 1], lookList: [0, 0, 0] },
  { positionList: [2, 2, 0], upList: [0, 1, 0], lookList: [0, 0, 0] },
  { positionList: [0, 2, 2], upList: [0, 1, 0], lookList: [0, 0, 0] },
  { positionList: [2, 0, 2], upList: [0, 1, 0], lookList: [0, 0, 0] },
])

const greenBox = (positionList = [2, 0, 0], upList = [0, 1, 0], lookList = [0, 0, 0], domEl) => {
  const scene = new THREE.Scene()
  const camera = new THREE.PerspectiveCamera( 75, domEl.clientWidth / domEl.clientHeight, 0.1, 1000 )

  const axesHelper = new THREE.AxesHelper( 3 )
  scene.add( axesHelper )

  const renderer = new THREE.WebGLRenderer()
  renderer.setSize( domEl.clientWidth, domEl.clientHeight )
  domEl.appendChild( renderer.domElement )

  const geometry = new THREE.BoxGeometry( 1, 1, 1 )
  const material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } )
  const cube = new THREE.Mesh( geometry, material )
  scene.add( cube )

  camera.position.set(...positionList)
  camera.up.set(...upList)
  camera.lookAt(...lookList)

  function animate() {
    requestAnimationFrame( animate )
    renderer.render( scene, camera )
  }
  animate()

  window.addEventListener( 'resize', onWindowResize )
  function onWindowResize() {
    camera.aspect = domEl.clientWidth / domEl.clientHeight
    camera.updateProjectionMatrix()
    renderer.setSize( domEl.clientWidth, domEl.clientHeight )
  }
}

onMounted(() => {
  demoList.value.forEach((demoItem, index) => {
    greenBox(demoItem.positionList, demoItem.upList, demoItem.lookList, domEl.value[index])
  })
})
</script>

<template>
  <div class="domEl-class w-screen h-screen flex flex-wrap gap-2">
    <div class="" v-for="(item, index) in demoList" :key="index">
      <div ref="domEl" style="height: calc(100% - 70px)"></div>
      <span class="text-blue-700">
        camera.position.set( {{ item.positionList.join(',') }} ) <br/>
        camera.up.set({{ item.upList.join(',') }}) <br/>
        camera.lookAt({{ item.lookList.join(',') }})
      </span>
    </div>
  </div>
</template>

<style scoped lang="scss">
.domEl-class {
  container-type: inline-size;
  >div {
    width: calc(25cqw - 1.5rem / 4);
    height: calc(33cqh - 1.5rem / 3);
  }
}
</style>